function getUniqId(){
	return 't_' + Math.floor(Math.random()*1000) ;
}

function getUniqueParam(){
	return 'param_' + Math.floor(Math.random()*1000000) ;
}

function showHideOptions(div){
	var display = div.nextSibling.style.display ;
	
	if(display == 'none'){
		div.nextSibling.style.display = 'block' ;
		div.value = 'cacher' ;
	}
	else{
		div.nextSibling.style.display = 'none' ;
		div.value = 'afficher les options' ;
	}
	
}

function createLi(inner){
	var el = document.createElement('li') ;
	el.className = "formElement" ;
	
	if(typeof(inner) != 'undefined') el.innerHTML = inner ;
	
	return el ;
}

function getSelectValue(text, selected){
	if(typeof(selected) == 'undefined') selected = false ;
	
	var option = document.createElement('option') ;
	option.value = text ;
	if(selected) option.setAttribute('selected', 'selected') ;
	option.appendChild(document.createTextNode(text)) ;
	return option ;
}

function addSelectValue(li, input, text, selected){
	if(typeof(selected) == 'undefined') selected = false ;
	if(typeof(text) == 'undefined'){
		text = input.value ;
		input.value = '' ;
	}
	
	var select = li.getElementsByTagName('select')[0] ;
	select.appendChild(getSelectValue(text, selected)) ;
}

function addSelectValues(li, span){
	var fromEl = span.getElementsByClassName('from')[0] ;
	var from = parseInt(fromEl.value) ;
	
	var toEl = span.getElementsByClassName('to')[0] ;
	var to = parseInt(toEl.value) ;
	
	var select = li.getElementsByTagName('select')[0] ;
	
	if(from<to){
		for(var i=from; i<=to; i++){
			select.appendChild(getSelectValue(i, false)) ;
		}
	}else{
		for(var i=from; i>=to; i--){
			select.appendChild(getSelectValue(i, false)) ;
		}
	}
	
	fromEl.value = '' ;
	toEl.value = '' ;
}

function removeValue(element) {
	var elementToRemove = element.parentNode.parentNode;
	var parent = elementToRemove.parentNode;
	parent.removeChild(elementToRemove);
	return false;
}

function getValue(type, name, text, selected){
	if(typeof(selected) == 'undefined') selected = false ;
	
	var rcLi = document.createElement('li') ;
	var label = document.createElement('label') ;
	var rcInput = document.createElement('input') ;
	var span = document.createElement('span') ;
	var textNode = document.createTextNode(text) ;
	
	rcInput.type = type ;
	rcInput.name = name ;
	rcInput.value = text ;
	rcInput.className = 'defaulValue' ;
	if(selected) rcInput.setAttribute('checked', 'checked') ;
	
	label.appendChild(rcInput) ;
	span.appendChild(textNode) ;
	label.appendChild(span) ;
	rcLi.appendChild(label) ;
	rcLi.appendChild(document.createTextNode(' - ')) ;
	
	var delSpan = document.createElement('span') ;
	var delLink = document.createElement('a') ;
	delLink.setAttribute('href', '#') ;
	delLink.setAttribute('onclick', 'javascript:return removeValue(this);') ;
	var delText = document.createTextNode('X') ;
	
	delLink.appendChild(delText);
	delSpan.appendChild(delLink);
	rcLi.appendChild(delSpan);
	
	return rcLi ;
}

function addValue(type, li, input, name, text, selected){
	if(typeof(selected) == 'undefined') selected = false ;
	if(typeof(text) == 'undefined'){
		text = input.value ;
		input.value = '' ;
	}
	
	var ul = li.getElementsByTagName('ul')[0] ;
	ul.appendChild(getValue(type, name, text, selected)) ;
}

function deleteFormElement(div){
	var parent = div.parentNode.parentNode ;
	parent.parentNode.removeChild(parent) ;
}

function getHiddenInput(name, value){
	return '<input type="hidden" name="'+name+'" value="'+value+'" />' ;
}

function cleanLabel(label){
	var text = label ;
	if(text.startsWith("<") && text.endsWith(">")){
		text = text.substring(1, text.length-1) ;
		text = text.replace(/ /g, "_") ;
		text = text.replace("[^A-Za-z0-9_]", "") ;
		text = text.toLowerCase() ;
		text = "<" + text + ">" ;
	}
	return text ;
}

function validateFieldType(){
	var fieldTypeCreatorElementsDiv = document.getElementById('fieldTypeCreatorElementsDiv') ;
	var fieldParams = fieldTypeCreatorElementsDiv.getElementsByClassName('fieldParams') ;
	
	var fields = [] ;
	var inputs = '' ;
	for(var i = 0 ; i<fieldParams.length; i++){
		var fieldParam = fieldParams[i] ;
		var type = fieldParam.id ;
		var text = cleanLabel(fieldParam.value) ;
		
		var field = {} ;
		field.type = type ;
		field.label = text ;
		field.secondLabel = '' ;
		
		var defaultValueNode = null ;
		var formOptions = new Array() ;
		if(type!='p' && type!='clear-both' && type!='title'){
			var name = fieldParam.name ;
			if(name == '') name = getUniqueParam() ;
			field.name = name ;
			
			defaultValueNode = fieldParam.parentNode.getElementsByClassName('defaultValue')[0] ;
		}
		formOptions = fieldParam.parentNode.parentNode.getElementsByClassName('formOption') ;
		
		switch(type){
			case 'text' : 
			case 'date' :
			case 'textarea' : 
				var defaultValue = null ;
				if(defaultValueNode!=null) defaultValue = defaultValueNode.value ;
				if(defaultValue!=null) field.defaultValue = defaultValue ;
				
				if (type == 'text') {
					var secondLabelNode = fieldParam.parentNode.getElementsByClassName('secondLabel')[0] ;
					if (secondLabelNode != null) {
						field.secondLabel = cleanLabel(secondLabelNode.value) ;
					}
				}
				break ;
			case 'radio' : 
			case 'checkbox' :
				var uls = fieldParam.parentNode.getElementsByTagName('ul') ;
				if(uls != null && uls.length>0){
					var lis = uls[0].getElementsByTagName('li') ;
					field.options = [] ;
					if(lis!=null){
						for(var j=0; j<lis.length; j++){
							var li = lis[j] ;
							var valNode = li.getElementsByTagName('label')[0].getElementsByTagName('input')[0] ;
							var jsonOption = {'value':valNode.value} ;
							if(valNode.checked) jsonOption.selected = true ;
							field.options.push(jsonOption) ;
						}
					}
				}
				break ;
			case 'select' :
				if(defaultValueNode!=null){
					field.options = [] ;
					for(var j=0; j<defaultValueNode.options.length; j++){
						var option = defaultValueNode.options[j] ;
						var jsonOption = {'value':option.value} ;
						jsonOption.selected = option.selected ;
						field.options.push(jsonOption) ;
					}
				}
				break;
			case 'hour' :
				var defaultValue = null ;
				if(defaultValueNode!=null){
					for(var j=0; j<defaultValueNode.options.length; j++){
						var option = defaultValueNode.options[j] ;
						if(option.selected){
							defaultValue = option.value;
							break;
						}
					}
				}
				if(defaultValue!=null) field.defaultValue = defaultValue ;
				break;
		}
		
		for(var k=0; k< formOptions.length; k++){
			var option = formOptions[k] ;
			switch(option.id){
				case "group":
					field.group = option.value ;
					break;
				case "mandatory":
					field.mandatory = option.checked ;
					break;
				case "minFieldLength":
					field.minLength = option.value ;
					break;
				case "maxFieldLength":
					field.maxLength = option.value ;
					break;
				case "style":
					field.style = option.value ;
					break;
				case "className":
					field.className = option.value ;
					break;
				case "numeric":
					field.numeric = option.checked ;
					break;
				case "float":
					field.float = option.checked ;
					break;
				case "string":
					field.string = option.checked ;
					break;
				case "displayWithValues":
					field.displayWithValues = option.checked ;
					break;
				case "image":
					field.image = option.checked ;
					break;
				case "imageWidth":
					field.imageWidth = option.value ;
					break;
				case "imageHeight":
					field.imageHeight = option.value ;
					break;
				case "displayAsImage":
					field.displayAsImage = option.checked ;
					break;
				case "sortAlphabetically":
					field.sortAlphabetically = option.checked ;
					break;
				case "regex":
					field.regex = option.value ;
					break;
				case "errorMessage":
					field.errorMessage = option.value ;
					break;
			}
		}
		
		fields.push(field) ;
	}
	
	var fieldTypes = [] ;
	var fieldType = {} ;
	fieldType.name = $('#field_type_name').val() ;
	fieldType.className = $('#fieldTypeCreatorClass').val() ;
	fieldType.style = $('#fieldTypeCreatorStyle').val() ;
	fieldType.elements = fields ;
	fieldTypes.push(fieldType) ;
	
	inputs = JSON.stringify(fieldTypes) ;
	
	document.getElementById('fieldTypeCreatorRealForm').value = inputs ;
	
	if(inputs != '') return true ;
	else return false ;
}

function getLabelInput(id, label, name, className){
	var cn = 'fieldParams';
	if (className !== undefined && className != '' && className != null) cn = className;
	return '<input type="text" id="'+id+'" value="'+label+'" name="'+name+'" class="labelInput '+cn+'" />' ;
}

function getBlockInput(id, label, name){
	return '<textarea id="'+id+'" class="textareaInput fieldParams" name="'+name+'">'+label+'</textarea>' ;
}

function createFormElement(type, parameters){
	if(typeof(parameters) == 'undefined') parameters = null ;
	
	var element = '' ;
	var defaultValue = '' ;
	var label = '&lt;change_this&gt;' ;
	var secondLabel = '' ;
	var name = '' ;
	var nameValue = '' ;
	var options = null ;
	var style = '' ;
	var className = '' ;
	var string = true ;
	var numeric = false ;
	var float = false ;
	var mandatory = false ;
	var minLength = '' ;
	var maxLength = '' ;
	var displayWithValues = true ;
	var image = false ;
	var group = '' ;
	
	var displayAsImage = false;
	
	var imageWidth = '' ;
	var imageHeight = '' ;
	
	var sortAlphabetically = false;
	var regex = '';
	var errorMessage = '';
	
	if(parameters != null){
		defaultValue = parameters.defaultValue ;
		label = parameters.label ;
		if (parameters.secondLabel != null) secondLabel = parameters.secondLabel ;
		name = 'name="'+parameters.name+'"' ;
		nameValue = parameters.name ;
		options = parameters.options ;
		style = parameters.style ;
		className = parameters.className ;
		string = parameters.string ;
		numeric = parameters.numeric ;
		float = parameters.float ;
		mandatory = parameters.mandatory ;
		minLength = parameters.minLength ;
		maxLength = parameters.maxLength ;
		displayWithValues = parameters.displayWithValues ;
		image = parameters.image;
		imageWidth = parameters.imageWidth;
		imageHeight = parameters.imageHeight;
		group = parameters.group;
		displayAsImage = parameters.displayAsImage;
		if (parameters.sortAlphabetically != null) sortAlphabetically = parameters.sortAlphabetically;
		if (parameters.regex != null) regex = parameters.regex;
		if (parameters.errorMessage != null) errorMessage = parameters.errorMessage;
	}
	
	switch(type){
		case 'text' :
			element  = '<span class="label">' ;
			element +=  	getLabelInput('text', label, nameValue) ;
			element +=  	'<input type="text" class="defaultValue" '+name+' value="'+defaultValue+'" />' ;
			element +=  	getLabelInput('', secondLabel, nameValue, 'secondLabel') ;
			element += '</span>' ;
			break ;
		case 'hour' :
			element  = '<span class="label">' ;
			element +=  	getLabelInput('hour', label, nameValue) ;
			element +=  	'<select class="defaultValue">' ;
			element += 			getSelectValue('', defaultValue=='').outerHTML ;
			var minutesArray = new Array ('00', '15', '30', '45'); 
	        for (var hour=0; hour<24; hour++) {
	            var sHour = hour;
	            if (hour<10) {
	                sHour = '0'+hour;
	            }
	            
	            for (var j=0; j<minutesArray.length; j++) {
	            	minute = minutesArray[j];
	                var hourMinute = sHour+':'+minute;
	                
					element += 	getSelectValue(hourMinute, defaultValue==hourMinute).outerHTML ;
	            }
			}
			element +=  	'</select>' ;
			element += '</span>' ;
			break ;
		case 'file' :
			element  = '<span class="label">' ;
			element +=  	getLabelInput('file', label, nameValue) ;
			element +=  	'<input type="file" class="defaultValue" '+name+' value="'+defaultValue+'" />' ;
			element += '</span>' ;
			break ;
		case 'date' :
			element  = '<span class="label">' ;
			element +=  	getLabelInput('date', label, nameValue) ;
			element += 		'<input type="text" class="defaultValue" '+name+' value="'+defaultValue+'" />' ;
			element += '</span>' ;
			break ;
		case 'textarea' :
			element  = '<span class="label">' ;
			element +=  	getLabelInput('textarea', label, nameValue) ;
			element +=  	'<textarea class="defaultValue" '+name+'>'+defaultValue+'</textarea>' ;
			element += '</span>' ;
			break ;
		case 'radio' :
		case 'checkbox' :
			var uniqId = (nameValue!='')?nameValue:getUniqId() ;
			
			element  = '<span>' ;
			element +=		getLabelInput(type, label, nameValue) ;
			element += 		'<ul>' ;
			if(options!=null){
				for(var i=0; i<options.length; i++){
					var option = options[i] ;
					element += getValue(type, uniqId, option.value, option.selected).outerHTML ;
				}
			}
			element += 		'</ul>' ;
			element += '</span>' ;
			element += 	'<span> Ajouter une valeur : <input type="text" /><input type="button" value="+" onclick="javascript:addValue(\''+type+'\', this.parentNode.previousSibling, this.previousSibling, \''+uniqId+'\')" /></span>' ;
			break ;
		case 'title' :
			element  = '<span class="title">' ;
			element +=  	getLabelInput('title', label, nameValue) ;
			element += '</span>' ;
			break ;
		case 'p' :
			element  = '<span class="text">' ;
			element +=  	getBlockInput('p', label, nameValue) ;
			element += '</span>' ;
			break ;
		case 'clear-both' :
			element  = '<span class="clear-both">' ;
			element += 	   '<input type="hidden" id="clear-both" class="fieldParams" name="'+nameValue+'" value="&lt;div style=&quote;clear-both&quote;&gt;&lt;div&gt;" />' ;
			element += '</span>' ;
			element += '&lt;div style="clear-both"&gt;&lt;div&gt;' ;
			break ;
		case 'select' :
			element  =  '<span class="label">' ;
			element +=  	getLabelInput('select', label, nameValue) ;
			element +=  	'<select class="defaultValue">' ;
			if(options == null) options = [{"value":"", "selected":true}] ;
			if(options!=null){
				for(var i=0; i<options.length; i++){
					var option = options[i] ;
					element += getSelectValue(option.value, option.selected).outerHTML ;
				}
			}
			element +=  	'</select>' ;
			element +=  '</span>'  ;
			element += 	'<span> Ajouter une valeur : <input type="text" /><input type="button" value="+" onclick="javascript:addSelectValue(this.parentNode.parentNode, this.previousSibling)" /></span>' ;
			element += 	'<span> Ajouter une liste de valeurs de : <input type="text" size="1" class="from" /> à <input type="text" size="1" class="to" /><input type="button" value="+" onclick="javascript:addSelectValues(this.parentNode.parentNode, this.parentNode)" /></span>' ;
			break ;
	}
	element += '<span class="formOptions">' ;
	
	element += '<input type="button" onclick="javascript:showHideOptions(this)" value="afficher les options" />' ;
	
	element += '<ul class="options" style="display:none;">' ;
	if(type!='p' && type!='clear-both' && type!='title'){
		
		var mc = (mandatory)?'checked="checked"':'' ;
	
		element += 		'<li><label><input type="checkbox" class="formOption" id="mandatory" '+mc+' />Obligatoire</label></li>' ;
		element += 		'<li><label>Message d\'erreur : <input type="text" class="formOption" id="errorMessage" value="'+errorMessage+'" /></label></li>' ;
		
		if(type == 'file'){
			var uniqId = getUniqId() ;
			var ic = ((image)?'checked="checked" ':'');
			var fc = ((!image)?'checked="checked" ':'');
			
			element +=		'<li class="file_image_options">' ;
			element +=			'<label>';
			element +=				'<input type="radio" name="'+uniqId+'" class="formOption" id="file" value="file" '+fc+'/>';
			element +=				'Fichier' ;
			element +=			'</label>' ;
			element +=			' - ' ;
			element +=			'<label>';
			element +=				'<input type="radio" name="'+uniqId+'" class="formOption" id="image" value="image" '+ic+'/>';
			element +=				'Image' ;
			element +=			'</label>' ;
			
			
			if(image){
				element +=			' - ';
				element +=			'<span class="image_options">';
				element +=				'<label>';
				element +=					'Largeur : ' ;
				element +=					'<input type="text" class="formOption" id="imageWidth" style="width:40px" value="'+imageWidth+'" />';
				element +=					' px' ;
				element +=				'</label>' ;
				element +=				' - ' ;
				element +=				'<label>';
				element +=					'Hauteur : ' ;
				element +=					'<input type="text" class="formOption" id="imageHeight" style="width:40px" value="'+imageHeight+'" />';
				element +=					' px' ;
				element +=				'</label>' ;
				element +=			'</span>';
			}
			
			element +=		'</li>' ;
			
		}else if(type == 'text' || type == 'textarea'){
			element += 		'<li>' ;
			element += 			'<label>Taille min : <input type="text" class="formOption" id="minFieldLength" style="width:40px" value="'+minLength+'" /></label>' ;
			element +=			' - ' ;
			element += 			'<label>Taille max : <input type="text" class="formOption" id="maxFieldLength" style="width:40px" value="'+maxLength+'" /></label>' ;
			element += 		'</li>' ;
			
			element += 		'<li><label>Regex : <input type="text" class="formOption" id="regex" value="'+regex+'" /></label></li>' ;
			
			if(type == 'text'){
				var uniqId = getUniqId() ;
				var sc = (string)?'checked="checked"':'' ;
				var nc = (numeric)?'checked="checked"':'' ;
				var fc = (float)?'checked="checked"':'' ;
				
				
				element += 		'<li>' ;
				element += 			'<label><input type="radio" name="'+uniqId+'" class="formOption" id="string" '+sc+' />Chaines de caractères</label>' ;
				element +=			' - ' ;
				element += 			'<label><input type="radio" name="'+uniqId+'" class="formOption" id="numeric" '+nc+' />Nombre entier</label>' ;
				element +=			' - ' ;
				element += 			'<label><input type="radio" name="'+uniqId+'" class="formOption" id="float" '+fc+' />Nombre réel</label>' ;
				element += 		'</li>' ;
				
				var di = (displayAsImage)?'checked="checked"':'' ;
				
				element += 		'<li>' ;
				element += 			'<label><input type="checkbox" name="'+uniqId+'" class="formOption" id="displayAsImage" '+di+' />Afficher sous forme d\'image</label>' ;
				element += 		'</li>' ;
			}
		} else if(type=="checkbox" || type=="radio" || type=="select"){
			var sa = (sortAlphabetically)?'checked="checked"':'' ;
			element += 		'<li><label><input type="checkbox" class="formOption" id="sortAlphabetically" '+sa+'/>Tri alphabétique</label></li>' ;
		}
		
		
	}else{
		var dv = (displayWithValues)?'checked="checked"':'' ;
		
		element += 		'<li><label><input type="checkbox" class="formOption" id="displayWithValues" '+dv+' />Afficher avec les réponses</label></li>' ;
	}
	element += 		'<li><label>Style : <input type="text" class="formOption" id="style" value="'+style+'" /></label></li>' ;
	element += 		'<li><label>Classe : <input type="text" class="formOption" id="className" value="'+className+'" /></label></li>' ;
	element += 		'<li><label>Groupe : <input type="text" class="formOption" id="group" value="'+group+'" /></label></li>' ;
	element += '</ul>' ;
	
	element += '<input type="button" onclick="javascript:deleteFormElement(this)" value="supprimer" />' ;
	element += '</span>' ;
	
	return element ;
}

(function($){
	$.fn.formFieldTypeCreator = function(options) {
		
		var dragged = false ;
		
		function createMenuElement(id, text){
			var el = createLi() ;
			
			var span = document.createElement('span') ;
			span.className = 'menuElement' ;
			span.appendChild(document.createTextNode(text)) ;
			span.id = id ;
			el.appendChild(span) ;
			
			return el ;
		}
		
		// Options par defaut
		var defaults = {
		};
				
		var options = $.extend(defaults, options);
		
		this.each(function(){
				
			var obj = $(this);
			
			var _preventDefault = function(evt) { evt.preventDefault(); };
			$(".formElement").bind("dragstart", _preventDefault).bind("selectstart", _preventDefault).bind("drop", _preventDefault);
			
			var fieldTypeCreatorMenuDiv = document.getElementById('fieldTypeCreatorMenu') ;
			var list = document.createElement('ul') ;
			list.appendChild(createMenuElement('text', 'Champs Texte')) ;
			list.appendChild(createMenuElement('textarea', 'Champs de bloc de texte')) ;
			list.appendChild(createMenuElement('date', 'Date')) ;
			list.appendChild(createMenuElement('hour', 'Champs heure')) ;
			list.appendChild(createMenuElement('file', 'Fichier')) ;
			list.appendChild(createMenuElement('select', 'Select')) ;
			list.appendChild(createMenuElement('radio', 'Bouton Radio')) ;
			list.appendChild(createMenuElement('checkbox', 'Case à cocher')) ;
			list.appendChild(createMenuElement('title', 'Titre')) ;
			list.appendChild(createMenuElement('p', 'Texte libre')) ;
			list.appendChild(createMenuElement('clear-both', 'Clear both')) ;
			fieldTypeCreatorMenuDiv.appendChild(list) ;
			
			var realFormInput = document.createElement('input') ;
			realFormInput.type = 'hidden' ;
			realFormInput.name = 'fields' ;
			realFormInput.id = 'fieldTypeCreatorRealForm' ;
			$(obj).append(realFormInput) ;
			
			$( "#fieldTypeCreatorMenu .formElement" ).draggable({ 
				revert: 'invalid',
				connectToSortable: '.fieldTypeCreatorElements',
				containment: '#fieldTypeCreator',
				helper: 'clone',
				start: function(ui, event) {
					dragged = true;
				}
			});
			
			$( ".fieldTypeCreatorElements" ).sortable({
				placeholder: 'ui-state-highlight'
			});

			$(".fieldTypeCreatorElements").droppable({
		        accept: ".formElement",
		        activeClass: "drop-active",
		        hoverClass: "drop-hover",
		        drop: function(event, ui) {
		            if(dragged){
		            	var el = ui.draggable.find('span') ;
		            	var type = el.attr('id') ;
		            	ui.draggable.html(createFormElement(type)) ;
		            }
		            dragged = false ;
		        }
		    });

			
		});
		// On continue le chainage JQuery
		return this;
	};})(jQuery);